        AMSTRAD ACTION MAGAZINE
         JAN 1986 - ISSUE 004

----------------------------------------
****** Design Your Own Graphics! *******
----------------------------------------

A great type-in utility to allow you super-fast graphic symbol creation

----------------------------------------
004 - User Defined Graphics
----------------------------------------

This classy listing is going to appeal to two sorts of people. On one level it can be used for some enjoyable doodling as a clever little art program. But it can also be put to very sophisticated use by anyone wanting to create their own graphic symbols for use in programs - hence the program's title User Defined Graphics.
If you're a programmer you'll know that the computer stores letters, punctuation symbols and various other graphic shapes coded with numbers ranging from 33 to 255 (the so-called ASCII codes). You can print these on screen using the command CHR$. For example PRINT CHR$(65) will print the letter A.
What the listing does is to allow you to redefine the graphic shape associated with each of these numbers. So if you wanted to change the shape of the "a" or turn it into a little space-ship or a telephone or a face, this program will let you do that very easily. You could use it to design a new character set which you could load in and run every time you got tired of the type of print Arnold normally uses. Or, if you don't want to mess around with the keyboard, you can simply define graphic shapes for the numbers above 128 and then make use of these in your own programs - once you're happy with the shapes you've created, this listing will actually create the program lines needed to generate them again instantly whenever needed.
Many thanks (and a nice cheque) to the author, DAVID MUIR of Plymouth.

Program Instructions

When the program is run a grid of nine large squares is displayed on screen. Each of these represents a single user-defined graphic and is further divided into a grid of 64 small squares. There is a cursor in the grid top left. To the right is a block of nine numbers which is simply a guide to the numbering of the large squares.
The cursor can be moved around the grid with the cursor keys. If the COPY key is pushed then the small square at the cursor position will be filled if empty, or emptied if filled. If SHIFT is pressed while using the cursor keys, a continuous drawing (or erasing) effect is possible.
There are a host of commands to save you time. As a general rule, there are two types of command: a small letter + number (1-9) operates on the specified large square, while a capital letter operates on the whole grid.

E - EMPTY the whole grid.
F - Fill the whole grid.
H - horizontally MIRROR grid.
V - vertically mirror grid.
A - ROTATE grid 90 degrees anti-clockwise.
C - rotate grid 90 degrees clockwise.
The commands e,f,h,v,a and c followed by a number (1-9) have the equivalent effect to the above on the specified UDG square.

U (number) - MOVE the whole grid design up the specified number of aquares.
D (number) - the same, but down.
L (number) - the same, but left.
R (number) - the same, but right.
m (number 1)(number 2) - COPY the contents of UDG square 1 to square 2.
P (0-2) - PICTURE the grid design. This reveals what the grid would look like in each of the three graphics modes 0-2.
N - CREATE program lines to store your UDGs. For each of the nine in turn you will be asked if you want to save it. Aswer "Y" and you are asked to input the ASCII code number you want to store it under (33-255). If you press ENTER here instead of a number, the program will store the first UDG at 255, the next at 254 and so on. Next you are asked to press 0 on the numeric keypad to store the UDG and take you on to the next one.
Z - DELETE the program from memory leaving just the new lines you've created (if any) starting from program line 1000. Don't use this command until you've finished all your designing.
If you then want to save the program lines you've created, add new lines with the command PRINT CHR$(number), where the number is the relevant ASCII code (33-255).
Happy doodling.

----------------------------------------

5 ' User Defined Graphics
6 ' by David Muir
7 ' *** DO NOT CHANGE LINE NUMBERS !!! ***
10 GOTO 290
15 a(t,u,v,w)=1-a(t,u,v,w):GOTO 30
20 LOCATE x,y:PEN 0:PRINT CHR$(254);:LOCATE x,y:PEN 1:PRINT CHR$(255);:RETURN
25 CLS #3:PRINT #3,"Next?"+CHR$(7)
30 a$=INKEY$:IF a$="" THEN 30 ELSE IF a$="h" OR a$="v" OR a$="a" OR a$="c" THEN 75 ELSE IF a$="H" OR a$="V" OR a$="A" OR a$="C" OR a$="L" OR a$="R" OR a$="U" OR a$="D" THEN 130
35 IF a$="F" OR a$="E" THEN 190 ELSE IF a$="f" OR a$="e" THEN 195 ELSE a=ASC(a$):IF a=&E0 THEN 15
40 IF (a>&EF AND a<&F4) THEN 45 ELSE IF UPPER$(a$)="M" THEN 215 ELSE IF (a>&F3 AND a<&F8) THEN 70 ELSE IF UPPER$(a$)="P" THEN 265 ELSE IF UPPER$(a$)="N" THEN 335 ELSE IF UPPER$(a$)="Z" THEN 260 ELSE GOTO 30
45 PEN (a(t,u,v,w)):LOCATE x,y:PRINT CHR$(254);:PEN 1
50 x=x-1*(a=&F3 AND x<24)+1*(a=&F2 AND x>1)
55 y=y-1*(a=&F1 AND y<24)+1*(a=&F0 AND y>1)
60 v=INT((x-1)/8)+1:w=INT((y-1)/8)+1:t=x-8*(v-1):u=y-8*(w-1)
65 LOCATE x,y:PEN 0:PRINT CHR$(254);:LOCATE x,y:PEN 1:PRINT CHR$(255);:GOTO 30
70 a(t,u,v,w)=1-a(t,u,v,w):a=a-4:GOTO 45
75 CLS #3:PRINT #3,"Square Num?"+CHR$(7)
80 q$=INKEY$:IF q$="" THEN 80 ELSE IF (q$>"9" OR q$<"1") THEN 80 ELSE q=VAL(q$):CLS #3
85 p=INT((q-1)/3)+1:q=q-((p-1)*3)
90 FOR i=1 TO 8:FOR j=1 TO 8:c(i,j)=a(i,j,q,p):NEXT:NEXT
95 IF a$="h" THEN FOR i=1 TO 8:FOR j=1 TO 8:a(i,j,q,p)=c(9-i,j):NEXT:NEXT
100 IF a$="v" THEN FOR i=1 TO 8:FOR j=1 TO 8:a(i,j,q,p)=c(i,9-j):NEXT:NEXT
105 IF a$="a" THEN FOR i=1 TO 8:FOR j=1 TO 8:a(i,j,q,p)=c(9-j,i):NEXT:NEXT
110 IF a$="c" THEN FOR i=1 TO 8:FOR j=1 TO 8:a(i,j,q,p)=c(j,9-i):NEXT:NEXT
115 f=(p-1)*8:e=(q-1)*8
120 FOR i=1 TO 8:FOR j=1 TO 8:LOCATE e+i,f+j:PEN (a(i,j,q,p)):PRINT CHR$(254);:NEXT:NEXT:GOSUB 20
125 GOTO 25
130 CLS #3:PRINT #3,"Compiling...":FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:b(k+(j-1)*8,i+(h-1)*8)=a(k,i,j,h):NEXT:NEXT:SOUND 1,478,1:NEXT:NEXT
131 IF a$="L" OR a$="R" OR a$="U" OR a$="D" THEN 152
135 IF a$="H" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=b(25-i,j):NEXT:SOUND 1,329,1:NEXT
140 IF a$="V" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=b(i,25-j):NEXT:SOUND 1,329,1:NEXT
145 IF a$="A" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=b(25-j,i):NEXT:SOUND 1,329,1:NEXT
150 IF a$="C" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=b(j,25-i):NEXT:SOUND 1,329,1:NEXT
151 GOTO 175
152 CLS #3:PRINT #3,"Number 1-7";CHR$(7);
153 q$=INKEY$:IF q$>"7" OR q$<"1" THEN 153 ELSE q=VAL(q$):CLS #3:PRINT #3,"Compiling..."
155 IF a$="L" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=-b(i+q+24*(i>24-q),j)*(i<25-q):NEXT:SOUND 1,329,1:NEXT
160 IF a$="R" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=-b(i-q-24*(i<q+1),j)*(i>q):NEXT:SOUND 1,329,1:NEXT
165 IF a$="D" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=-b(i,j-q-24*(j<q+1))*(j>q):NEXT:SOUND 1,329,1:NEXT
170 IF a$="U" THEN FOR i=1 TO 24:FOR j=1 TO 24:e=INT((i-1)/8)+1:f=i-((e-1)*8):g=INT((j-1)/8)+1:h=j-((g-1)*8):a(f,h,e,g)=-b(i,j+q+24*(j>24-q))*(j<25-q):NEXT:SOUND 1,329,1:NEXT
175 CLS #3:FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:LOCATE k+(j-1)*8,i+(h-1)*8:PEN a(k,i,j,h):PRINT CHR$(254);
180 NEXT:NEXT:NEXT:NEXT:GOSUB 20
185 GOTO 25
190 CLS #3:n=-1*(a$="F"):FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:LOCATE k+(j-1)*8,i+(h-1)*8:PEN n:PRINT CHR$(254);:a(k,i,j,h)=n:NEXT:NEXT:NEXT:NEXT:GOSUB 20:GOTO 25
195 CLS #3:PRINT #3,"Square Num?"+CHR$(7)
200 q$=INKEY$:IF q$="" THEN 200 ELSE IF q$>"9" OR q$<"1" THEN 200 ELSE q=VAL(q$):n=-1*(a$="f"):CLS #3
205 p=INT((q-1)/3)+1:q=q-((p-1)*3):p1=(p-1)*8:q1=(q-1)*8
210 FOR i=1 TO 8:FOR j=1 TO 8:LOCATE q1+i,p1+j:a(i,j,q,p)=n:PEN n:PRINT CHR$(254);:NEXT:NEXT:GOSUB 20:GOTO 25
215 CLS #3:PRINT #3,"From (Num)?"+CHR$(7)
220 q$=INKEY$:IF q$="" THEN 220 ELSE IF q$>"9" OR q$<"1" THEN 220 ELSE q1=VAL(q$)
225 CLS#3:PRINT #3,"To (Num)?"+CHR$(7)
230 q$=INKEY$:IF q$="" THEN 230 ELSE IF q$>"9" OR q$<"1" THEN 230 ELSE q2=VAL(q$):IF q2=q1 THEN 215
235 CLS #3:p1=INT((q1-1)/3)+1:q1=q1-((p1-1)*3):p2=INT((q2-1)/3)+1:q2=q2-((p2-1)*3)
240 FOR i=1 TO 8:FOR j=1 TO 8:a(i,j,q2,p2)=a(i,j,q1,p1):NEXT:NEXT
245 f=(p2-1)*8:e=(q2-1)*8
250 FOR i=1 TO 8:FOR j=1 TO 8:LOCATE e+i,f+j:PEN (a(i,j,q2,p2)):PRINT CHR$(254);:NEXT:NEXT:GOSUB 20
255 GOTO 25
260 CLS:DELETE -530:END
265 CLS #3:PRINT #3,"Mode Num?"+CHR$(7)
270 ORIGIN 480,382:q$=INKEY$:IF q$="" THEN 270 ELSE IF q$>"2" OR q$<"0" THEN 270 ELSE q=VAL(q$):CLS #1:CLS #3
275 IF q=1 THEN FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:PLOT 2*((j-1)*8+k-1),-2*((h-1)*8+i-1),1-1*(a(k,i,j,h)=0):NEXT:NEXT:NEXT:NEXT:GOTO 25
280 IF q=2 THEN FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:PLOT 2*((j-1)*8+k-1),-4*((h-1)*8+i-1),a(k,i,j,h):DRAWR 0,2,1-1*(a(k,i,j,h)=0):NEXT:NEXT:NEXT:NEXT:GOTO 25
285 IF q=0 THEN FOR h=1 TO 3:FOR i=1 TO 8:FOR j=1 TO 3:FOR k=1 TO 8:PLOT 4*((j-1)*8+k-1),-2*((h-1)*8+i-1),a(k,i,j,h):DRAWR 2,0,1-1*(a(k,i,j,h)=0):NEXT:NEXT:NEXT:NEXT:GOTO 25
290 DIM a(8,8,3,3),b(24,24),c(8,8),d(8,8):x=1:y=1:t=1:u=1:v=1:w=1:linum=1000:ch=255
295 MODE 1:INK 1,1:INK 0,21:INK 3,11:INK 2,24:BORDER 11:CLS:ORIGIN 0,15
300 FOR i=0 TO 384 STEP 16:MOVE 0,i:DRAWR 384,0,3:MOVE i,0:DRAWR 0,384,3:NEXT
305 FOR i=0 TO 384 STEP 128:MOVE 0,i:DRAWR 384,0,2:MOVE i,0:DRAWR 0,384,2:NEXT
310 FOR i=0 TO 2:FOR j=1 TO 3:LOCATE 25+j,i+2:PRINT CHR$(48+j+i*3):NEXT:NEXT
315 WINDOW #1,30,40,1,8:WINDOW #2,26,40,9,25:WINDOW #3,26,40,23,25
320 PAPER #3,0:CLS #3
325 SYMBOL AFTER 126:SYMBOL 254,0,127,127,127,127,127,127,127:SYMBOL 255,0,85,42,85,42,85,42,85
330 PRINT CHR$(22)+CHR$(1):LOCATE 1,1:PRINT CHR$(255);:GOTO 25
335 CLS #3:PRINT #3,"Compiling...":FOR h=1 TO 3:FOR i=1 TO 3:FOR j=1 TO 8:l=0:FOR k=1 TO 8
340 l=2*1+a(k,j,i,h):NEXT
345 d((h-1)*3+i-1,j)=1:NEXT:SOUND 1,478,1:NEXT:NEXT
350 i=0
355 i=i+1:CLS #2:PRINT #2,"(";i;")":PRINT #2:FOR j=1 TO 8
360 PRINT #2,d(i-1,j):NEXT
365 CLS #3:PRINT #3,"Save?"+CHR$(7)
370 a$=INKEY$:a$=UPPER$(a$):IF a$="Y" THEN 385 ELSE IF a$<>"N" THEN 370
375 CLS #3
380 IF i<9 THEN 355 ELSE CLS #2:GOTO 25
385 CLS #3:PRINT #3,"Char Number?"+CHR$(7)
390 INPUT #3,a$:IF a$="" THEN IF ch=33 THEN 385 ELSE linum=linum+10:char=ch:ch=ch-1:GOTO 405
392 IF LEN(a$)>3 THEN 385 ELSE flag=0:FOR j=1 TO LEN(a$):IF MID$(a$,j,1)>"9" OR MID$(a$,j,1)<"0" THEN flag=1
395 NEXT:IF flag=1 THEN 385 ELSE IF VAL(a$)<33 OR VAL(a$)>255 THEN 385
400 char=VAL(a$):ch=char:ch=ch-1:linum=linum+10
405 m$=STR$(linum)+"symbol "+STR$(char)+","+STR$(d(i-1,1))+","+STR$(d(i-1,2))+","+STR$(d(i-1,3))+","+STR$(d(i-1,4))+","+STR$(d(i-1,5))+","+STR$(d(i-1,6))+","+STR$(d(i-1,7))+","+STR$(d(i-1,8))+CHR$(13)
410 m$=m$+"WINDOW SWAP 0,3:KEY 128,CHR$(48):GOTO 380"+CHR$(13)
415 KEY 128,m$:PRINT #3,"0 On Pad When"+CHR$(7):WINDOW SWAP 0,3:END
530 REM Break Point
1000 SYMBOL AFTER 33
1010 SYMBOL 33,0,0,0,0,0,0,0,0


----------------------------------------
All files typed in and saved to .dsk
file (NVG) by Mr. Michael N. Till.
..The Devil's Phoenix..

Any problems or queeries please
e-mail: redstick@hotmail.co.uk